package command

import (
	"fmt"
	"os"
	"pan/api"
	"pan/common/conf"
	"pan/common/log"

	"github.com/jedib0t/go-pretty/v6/table"
)

type DirCommand struct {
	dir    string
	owner  string
	simple bool
}

func NewDirCommand() *DirCommand {
	return &DirCommand{}
}

func (d *DirCommand) Run(opts []*Option, args []string) {
	if !d.parseOption(opts) {
		return
	}

	if !conf.IsTokenValid() {
		panic("token is invalid, you must login first")
	}

	req := &api.DirRequest{
		Dir:   d.dir,
		Owner: d.owner,
		By:    "time",
		Sort:  "desc",
	}

	resp, err := api.DirApi(conf.GlobalToken.Tokenid, req)
	if err != nil {
		panic(err)
	}
	if d.simple {
		d.printSimpleDirs(resp.Dirs)
		d.printSimpleFiles(resp.Files)
	} else {
		d.printDirs(resp.Dirs)
		d.printFiles(resp.Files)
	}
}

func (d *DirCommand) parseOption(opts []*Option) bool {
	for _, opt := range opts {
		switch opt.Name {
		case "dir":
			d.dir = opt.StrValue
		case "owner":
			d.owner = opt.StrValue
		case "simple":
			d.simple = opt.BoolValue
		}
	}
	if d.dir == "" {
		log.Error("doc dir is invalid")
		return false
	}
	return true
}

func (d *DirCommand) Arguments() []Argument {
	return nil
}

func (d *DirCommand) Options() []*Option {
	return []*Option{
		{
			ShortName:    "d",
			Name:         "dir",
			Description:  "search doc dir",
			OptType:      StrOption,
			DefaultValue: "",
		},
		{
			ShortName:    "o",
			Name:         "owner",
			Description:  "doc dir's owner",
			OptType:      StrOption,
			DefaultValue: "",
		},
		{
			ShortName:    "s",
			Name:         "simple",
			Description:  "show simple content",
			OptType:      BoolOption,
			DefaultValue: false,
		},
	}
}

func (d *DirCommand) Description() string {
	return "Search doc dir"
}

func (d *DirCommand) printDirs(dirs []api.DirInfo) {
	if dirs == nil || len(dirs) == 0 {
		return
	}
	tbl := table.NewWriter()
	tbl.SetOutputMirror(os.Stdout)
	tbl.AppendHeader(table.Row{"#", "Dir"})
	tbl.AppendRow(table.Row{"", "docid", "name", "rev"})
	tbl.AppendSeparator()

	for i, dir := range dirs {
		tbl.AppendRow(table.Row{i + 1, dir.Docid, dir.Name, dir.Rev})
		tbl.AppendSeparator()
	}
	tbl.Render()
}

func (d *DirCommand) printFiles(files []api.FileInfo) {
	if files == nil || len(files) == 0 {
		return
	}
	tbl := table.NewWriter()
	tbl.SetOutputMirror(os.Stdout)
	tbl.AppendHeader(table.Row{"#", "File"})
	tbl.AppendRow(table.Row{"", "docid", "name", "rev"})
	tbl.AppendSeparator()

	for i, f := range files {
		tbl.AppendRow(table.Row{i + 1, f.Docid, f.Name, f.Rev})
		tbl.AppendSeparator()
	}
	tbl.Render()
}

func (d *DirCommand) printSimpleDirs(dirs []api.DirInfo) {
	if dirs == nil || len(dirs) == 0 {
		return
	}
	for _, dir := range dirs {
		fmt.Printf("D, %s, %s, %s\n", dir.Docid, dir.Name, dir.Rev)
	}
}

func (d *DirCommand) printSimpleFiles(files []api.FileInfo) {
	if files == nil || len(files) == 0 {
		return
	}
	for _, f := range files {
		fmt.Printf("F, %s, %s, %s\n", f.Docid, f.Name, f.Rev)
	}
}
